﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using yq.IService;
using System.ServiceModel;
using System.ServiceModel.Activation;
using yq.Task;
using Db;

namespace yq.Service
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class Task : ITask
    {
        /// <summary>
        /// 执行并返回
        /// </summary>
        /// <param name="taskId"></param>
        /// <returns></returns>
        public bool RunWait(string taskId)
        {
            var info = yq.Model.Logic.SysTask.Load(taskId);
            return new ReflectionLoad().Operating(info.RunPath, info.Rowid, info.Json);
        }

        /// <summary>
        /// 执行任务 异步
        /// </summary>
        /// <param name="taskId"></param>
        public void Run(string taskId)
        {
            var info = yq.Model.Logic.SysTask.Load(taskId);
            new ReflectionLoad().Operating(info.RunPath, info.Rowid, info.Json);
        }

        /// <summary>
        /// 循环执行任务
        /// </summary>
        /// <param name="taskNum"></param>
        public void ForRun(int taskNum)
        {
            IList<string> list = GetRun(taskNum);

            foreach (var taskId in list)
            {
                RunWait(taskId);
                Func<DbHelper, yq.CaCheRefresh, bool> dbfun = (cn, ca) =>
                {
                    var info = yq.Model.Logic.SysTask.Load(taskId);
                    info.State = Enums.SysTask.State.Wait;
                    new yq.Business.SysTaskDal().Update(info,cn);

                    cn.Commit();
                    return true;
                };

                Db.DBTrans.DoTrans(dbfun);
            }
        }

        /// <summary>
        /// 获取要执行的任务
        /// </summary>
        /// <param name="taskNum"></param>
        /// <returns></returns>
        public IList<string> GetRun(int taskNum)
        {
            Func<DbHelper, yq.CaCheRefresh, IList<string>> dbfun = (cn, ca) =>
            {
                IList<string> list = new List<string>();
                var dal = new yq.Business.SysTaskDal();
                //这里还需要执行一个复位操作

                var timeOutList = dal.GetList(obj => (obj.State == Enums.SysTask.State.Run || obj.OutTime < DateTime.Now) &&
                  obj.StartTime < DateTime.Now && obj.NextTime < DateTime.Now, cn);
                foreach (var timemodel in timeOutList)
                {
                    timemodel.State = Enums.SysTask.State.Wait;
                    dal.Update(timemodel, cn);
                }

                //获取要执行的任务列表
                var taskList = dal.GetList(obj => (obj.State == Enums.SysTask.State.Wait || obj.State == Enums.SysTask.State.Open) &&
                      obj.StartTime < DateTime.Now && obj.NextTime < DateTime.Now, cn);

                for (int i = 0; i < taskList.Count && i < taskNum; i++)
                {
                    taskList[i].State = Enums.SysTask.State.Run;
                    taskList[i].StartTime = DateTime.Now;
                    taskList[i].OutTime = DateTime.Now.AddSeconds(taskList[i].OutInterval);

                    //计算下一次任务执行时间
                    Calculate(taskList[i]);

                    dal.Update(taskList[i], cn);
                }

                cn.Commit();
                return list;
            };

            return Db.DBTrans.DoTrans(dbfun);
        }

        /// <summary>
        /// 计算下一次任务执行时间
        /// </summary>
        /// <param name="model"></param>
        private void Calculate(yq.Model.Logic.SysTask model)
        {
            DateTime now = model.StartTime < DateTime.Now ? DateTime.Now : model.StartTime;

            DateTime tp = new DateTime();

            //循环性任务
            if (model.Types == Enums.SysTask.Types.ForTask)
            {
                tp = DateTime.Now.AddSeconds(Convert.ToInt32(model.Interval));
            }
            //年格式
            else if (model.Types == Enums.SysTask.Types.Year)
            {
                tp = DateTime.ParseExact(model.Interval, "MMddHHmmss", null);
                tp.AddYears(now.Year);

                //如果已经过期 自动跳到下一个周期
                if (tp < now)
                {
                    tp = tp.AddYears(1);
                }
            }
            //月
            else if (model.Types == Enums.SysTask.Types.Mon)
            {
                tp = DateTime.ParseExact(model.Interval, "ddHHmmss", null);
                tp.AddYears(now.Year);
                tp.AddMonths(now.Month);
                if (tp < now)
                {
                    tp = tp.AddMonths(1);
                }
            }
            //日
            else if (model.Types == Enums.SysTask.Types.Day)
            {
                tp = DateTime.ParseExact(model.Interval, "HHmmss", null);
                tp.AddYears(now.Year);
                tp.AddMonths(now.Month);
                tp.AddDays(now.Day);
                if (tp < now)
                {
                    tp = tp.AddDays(1);
                }
            }

            model.NextTime = tp;
        }





   
    }
}
